<?php 
//I.F. Nuevo: 2010-02-03; ramarin

require_once($CFG->dirroot.'/'.$CFG->admin.'/report/moosisca/filters_workflow/text.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/moosisca/filters_workflow/select.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/moosisca/filters_workflow/statedate.php');
require_once($CFG->dirroot.'/'.$CFG->admin.'/report/moosisca/filters_workflow/workflow_filter_forms.php');


/**
 * workflow filtering wrapper class.
 */
class workflow_filtering {
  var $_fields;
  var $_addform;
  var $_activeform;

  /**
   * Contructor
   * @param array array of visible workflow fields
   * @param string base url used for submission/return, null if the same of current page
   * @param array extra page parameters
   */
  function workflow_filtering($showUsers = false, $fieldnames=null, $baseurl=null, $extraparams=null) {
    global $SESSION;

    if (!isset($SESSION->workflow_filtering)) {
        $SESSION->workflow_filtering = array();
    }

    if (empty($fieldnames)) {
    
        $fieldnames = array('state'=>0,
                'space_type'=>1,
                'createddate'=>1,
                'approveddate'=>1,
                'migrateddate'=>1);//, 'date'=>1);
                            
        if($showUsers){
            $fieldnames['realname'] = 1;
            $fieldnames['username'] = 1;
        }
    }

    $this->_fields  = array();

    foreach ($fieldnames as $fieldname=>$advanced) {
        if ($field = $this->get_field($fieldname, $advanced)) {
            $this->_fields[$fieldname] = $field;
        }
    }

    // fist the new filter form
    $this->_addform = new workflow_add_filter_form($baseurl, array('fields'=>$this->_fields, 'extraparams'=>$extraparams));
    if ($adddata = $this->_addform->get_data(false)) {
        foreach($this->_fields as $fname=>$field) {
            $data = $field->check_data($adddata);
            if ($data === false) {
                continue; // nothing new
            }
            if (!array_key_exists($fname, $SESSION->workflow_filtering)) {
                $SESSION->workflow_filtering[$fname] = array();
            }
            $SESSION->workflow_filtering[$fname][] = $data;
        }
        // clear the form
        $_POST = array();
        $this->_addform = new workflow_add_filter_form($baseurl, array('fields'=>$this->_fields, 'extraparams'=>$extraparams));
    }

    // now the active filters
    $this->_activeform = new workflow_active_filter_form($baseurl, array('fields'=>$this->_fields, 'extraparams'=>$extraparams));
    if ($adddata = $this->_activeform->get_data(false)) {
        if (!empty($adddata->removeall)) {
            $SESSION->workflow_filtering = array();

        } else if (!empty($adddata->removeselected) and !empty($adddata->filter)) {
            foreach($adddata->filter as $fname=>$instances) {
                foreach ($instances as $i=>$val) {
                    if (empty($val)) {
                        continue;
                    }
                    unset($SESSION->workflow_filtering[$fname][$i]);
                }
                if (empty($SESSION->workflow_filtering[$fname])) {
                    unset($SESSION->workflow_filtering[$fname]);
                } 
            }
        }
        // clear+reload the form
        $_POST = array();
        $this->_activeform = new workflow_active_filter_form($baseurl, array('fields'=>$this->_fields, 'extraparams'=>$extraparams));
    }
    // now the active filters
  }

  /**
   * Creates known workflow filter if present
   * @param string $fieldname
   * @param boolean $advanced
   * @return object filter
   */
  function get_field($fieldname, $advanced) {
    global $USER, $CFG, $SITE;
  
    $choices = array();
    $choices['evaluation'] = get_string('workFlowState.evaluation', 'report_moosisca');
    $choices['observations'] = get_string('workFlowState.observations', 'report_moosisca');
    $choices['approved'] = get_string('workFlowState.approved', 'report_moosisca');
    $choices['migrated'] = get_string('workFlowState.migrated', 'report_moosisca');
    
    $spaceTypes = moosisca_get_spaces_types();

    switch ($fieldname) {
      case 'state':          	return new workflow_filter_select('state', get_string('state', 'report_moosisca'), $advanced, 'state', $choices);
      case 'space_type':        return new workflow_filter_select('space_type', get_string('spaceType', 'report_moosisca'), $advanced, 'space_type', $spaceTypes);
      case 'realname':          return new workflow_filter_text('realname', get_string('fullnameuser'), $advanced, sql_fullname());
      case 'username':          return new workflow_filter_text('username', get_string('username'), $advanced, 'username');
      case 'createddate':       return new workflow_filter_statedate('createddate', get_string('workFlowState.createddate', 'report_moosisca'), $advanced, 'timecreated', 'created');
      case 'approveddate':      return new workflow_filter_statedate('approveddate', get_string('workFlowState.approveddate', 'report_moosisca'), $advanced, 'timecreated', 'approved');
      case 'migrateddate':      return new workflow_filter_statedate('migrateddate', get_string('workFlowState.migrateddate', 'report_moosisca'), $advanced, 'timecreated', 'migrated');
      default:                  return null;
    }
  }

  /**
   * Returns sql where statement based on active user filters
   * @param string $extra sql
   * @return string
   */
  function get_sql_filter($extra='') {
      global $SESSION;

      $sqls = array();
      $statesConditions = array();

      if ($extra != '') {
          $sqls[] = $extra;
      }

      if (!empty($SESSION->workflow_filtering)) {
          foreach ($SESSION->workflow_filtering as $fname=>$datas) {
              if (!array_key_exists($fname, $this->_fields)) {
                  continue; // filter not used
              }
              $field = $this->_fields[$fname];
              foreach($datas as $i=>$data) {
                    if (isset($field->_state)) {
                        $statesConditions[] = $field->get_sql_filter($data);
                    }
                    else {
                        $sqls[] = $field->get_sql_filter($data);
                    }
              }
          }
      }
      
        $res = array();
        if (count($statesConditions) > 0) {
            $res['statecondition'] = implode(' OR ', $statesConditions);
            $res['countstatecondition'] = count($statesConditions);
        }
        else {
            $res['statecondition'] = '';
            $res['countstatecondition'] = 0;
        }

        if (empty($sqls)) {
            $res['sqlcondition'] = '';
        }
        else {
            $res['sqlcondition'] = implode(' AND ', $sqls);
        }

        return $res;
  }

  /**
   * Print the add filter form.
   */
  function display_add() {
      $this->_addform->display();
  }

  /**
   * Print the active filter form.
   */
  function display_active() {
      $this->_activeform->display();
  }

}

/**
* The base user filter class. All abstract classes must be implemented.
*/
class workflow_filter_type {
  /**
   * The name of this filter instance.
   */
  var $_name;

  /**
   * The label of this filter instance.
   */
  var $_label;

  /**
   * Advanced form element flag
   */
  var $_advanced;

  /**
   * Constructor
   * @param string $name the name of the filter instance
   * @param string $label the label of the filter instance
   * @param boolean $advanced advanced form element flag
   */
  function workflow_filter_type($name, $label, $advanced) {
      $this->_name     = $name;
      $this->_label    = $label;
      $this->_advanced = $advanced;
  }

  /**
   * Returns the condition to be used with SQL where
   * @param array $data filter settings
   * @return string the filtering condition or null if the filter is disabled
   */
  function get_sql_filter($data) {
      error('Abstract method get_sql_filter() called - must be implemented');
  }

  /**
   * Retrieves data from the form data
   * @param object $formdata data submited with the form
   * @return mixed array filter data or false when filter not set
   */
  function check_data($formdata) {
      error('Abstract method check_data() called - must be implemented');
  }

  /**
   * Adds controls specific to this filter in the form.
   * @param object $mform a MoodleForm object to setup
   */
  function setupForm(&$mform) {
      error('Abstract method setupForm() called - must be implemented');
  }

  /**
   * Returns a human friendly description of the filter used as label.
   * @param array $data filter settings
   * @return string active filter label
   */
  function get_label($data) {
      error('Abstract method get_label() called - must be implemented');
  }
}
